#include "BlockQueue.hpp"
#include "Task.hpp"
#include <ctime>
#include <unistd.h>

int Add(int x, int y)
{
    return x + y;
}

void *consumer(void *args)
{
    BlockQueue<Task> *bq = (BlockQueue<Task> *)args;
    while (true)
    {
        Task t;
        bq->pop(&t);
        std::cout << pthread_self() <<" consumer : " << t.x_ << " + " << t.y_ << " = " << t() << std::endl;
        sleep(1);
    }
    return nullptr;
}

void *productor(void *args)
{
    BlockQueue<Task> *bq = (BlockQueue<Task> *)args;
    while (true)
    {
        int x = rand() % 1000 * 23691;
        int y = rand() % 1000 * 28945;

        Task t(x, y, Add);
        bq->push(t);
        std::cout << pthread_self() <<" productor: "<< x << " + " << y << " = ? " << std::endl;
    }
    return nullptr;
}

int main()
{
    srand((unsigned long)time(nullptr) ^ getpid());
    BlockQueue<Task> *bq = new BlockQueue<Task>();

    pthread_t c[2],p[2];
    pthread_create(c, nullptr, consumer, bq);
    pthread_create(c + 1, nullptr, consumer, bq);
    pthread_create(p, nullptr, productor, bq);
    pthread_create(p + 1, nullptr, productor, bq);

    pthread_join(c[0], nullptr);
    pthread_join(c[1], nullptr);
    pthread_join(p[0], nullptr);
    pthread_join(p[1], nullptr);
    delete bq;

    return 0;
}
